import { AfterViewInit, ViewChild } from '@angular/core';
import { Component }                from '@angular/core';
import { CountdownTimerComponent }  from './countdown-timer.component';

//// Local variable, #timer, version
@Component({
  selector: 'countdown-parent-lv',
  /**
   * 父组件不能通过数据绑定使用子组件的 start 和 stop 方法，也不能访问子组件的 seconds 属性。
   * 把本地变量 (#timer) 放到 (<countdown-timer>) 标签中，用来代表子组件。
   * 这样父组件的模板就得到了子组件的引用，于是可以在父组件的模板中访问子组件的所有属性和方法。
   * 在这个例子中，我们把父组件的按钮绑定到子组件的 start 和 stop 方法，
   * 并用插值表达式来显示子组件的 seconds 属性。
   */
  // 在这里给子组件设定了一个本地变量 (#timer),这样在父组件的模板中访问子组件的所有属性和方法。
  template: `
  <h3>Countdown to Liftoff (via local variable)</h3>
  <button (click)="timer.start()">Start</button>
  <button (click)="timer.stop()">Stop</button>
  <div class="seconds">{{timer.seconds}}</div>
  <countdown-timer #timer></countdown-timer>
  `,
  styleUrls: ['demo.css']
})

export class CountdownLocalVarParentComponent { }


//------------------------------------------------------------

// 父组件调用 ViewChild
/**
 * 这个 本地变量 方法是个简单便利的方法。但是它也有局限性，因为父组件 - 子组件的连接必须全部在父组件的模板中进行。
 * 父组件本身的代码对子组件没有访问权。
 * 
 * 如果父组件的 类 需要读取子组件的属性值或调用子组件的方法，就不能使用 本地变量 方法。
 * 
 * 当父组件 类 需要这种访问时，可以把子组件作为 ViewChild ， 注入 到父组件里面。
 */

//// View Child version
@Component({
  selector: 'countdown-parent-vc',
  template: `
  <h3>Countdown to Liftoff (via ViewChild)</h3>
  <button (click)="start()">Start2</button>
  <button (click)="stop()">Stop2</button>
  <div class="seconds">{{ seconds() }}</div>
  <countdown-timer></countdown-timer>
  `,
  styleUrls: ['demo.css']
})

export class CountdownViewChildParentComponent implements AfterViewInit {

  // 通过 ViewChild 装饰器导入这个引用
  @ViewChild(CountdownTimerComponent)
  // 通过 @ViewChild 属性装饰器，将子组件 CountdownTimerComponent 注入到私有属性 timerComponent 里面。
  private timerComponent: CountdownTimerComponent;

  seconds() { return 0; }

  // 挂上 AfterViewInit 生命周期钩子
  ngAfterViewInit() {
    // Redefine `seconds()` to get from the `CountdownTimerComponent.seconds` ...
    // but wait a tick first to avoid one-time devMode
    // unidirectional-data-flow-violation error
    setTimeout(() => this.seconds = () => this.timerComponent.seconds, 0);
  }

  start() { this.timerComponent.start(); }
  stop() { this.timerComponent.stop(); }
}